<?php

//TODO:
//implement page specific

// display stuff
// tab title: display value

// database stuff
// table: database table name:
// first foreign key pair is the data entry's page
// others are database selectable
// current_doc: the currently edited document, used for filling in foreign key
// listing fields: summary fields to show in the quick list

// manager stuff
// roles, templates: which roles or templates to show this field for
// doc: show this for a specific page

// this basically allows one to build a model for the database
class df_table_info{
	//a foregin key column can be either linked to a databse name or a page parent id
	protected $table, $foreign_keys,$listing_fields, $primary_key='id',$where='',$parent_table='', $summary_fields,
			$linkedTables, $RecursivelinkedTables, $recursiveSummaryfields;
	// note that because the first foreign key field refers to the associated document's parent, 
	// it doesn't really matter, because the foreign key must be the document itself
	// column holds doc_id, this field holds doc_id_id?!
	function __construct($table, $foreign_keys='',$summary_fields=''){
		$this->table = $table;
		$this->foreign_keys = $foreign_keys;
		$this->summary_fields = $summary_fields;
		
		$this->populateChildrensParents();
	}
	
	function getResouceIdColName(){
		return $this->foreign_keys[0];
	}
	
	function populateChildrensParents(){
		foreach($this->getLinkedTables() as $linked_table_name => $linked_table_info){
			$linked_table_info->setParentTable($this);
		}
	}
	
	function getLinkedTables(){ //todo: confirm this syntax?
		if (isset($this->linkedTables)) return $this->linkedTables;

		
		$this->linkedTables = Array();

		if (isset($this->foreign_keys) && $this->foreign_keys != ''){
			foreach ($this->foreign_keys as $fKeyName => $fKeyVal){
				if (is_object($fKeyVal)){ 
					$this->linkedTables[$fKeyName] = $fKeyVal;
				}
			}
		}

		return $this->linkedTables;

	}
	
	function getRecursivelyLinkedTables(){
		if (isset($this->RecursivelinkedTables)) return $this->RecursivelinkedTables;
		
		$this->RecursivelinkedTables = $this->getLinkedTables();

		foreach ($this->linkedTables as $table_name => $tablePointer){
			if(count($this->RecursivelinkedTables)){
				
				$this->RecursivelinkedTables = array_merge($this->RecursivelinkedTables, $tablePointer->getRecursivelyLinkedTables());
			}else{
				$this->RecursivelinkedTables = $tablePointer->getRecursivelyLinkedTables();
			}
		}
		
		return $this->RecursivelinkedTables;
		
	}
	
	function getRecursiveSummaryFields(){
		if (isset($this->recursiveSummaryfields)) return $this->recursiveSummaryfields;
		
		$this->recursiveSummaryfields = array();
		
		//use absolute naming in case of matching table names:
		if (isset($this->summary_fields) && $this->summary_fields != ''){
			foreach ($this->summary_fields as $fieldName => $fieldTitle){
				$this->recursiveSummaryfields[$this->table.'.'.$fieldName] = $fieldTitle;
				
			}
		}
						
		foreach ($this->getLinkedTables() as $table_name => $tablePointer){
			$this->recursiveSummaryfields = array_merge($this->recursiveSummaryfields, $tablePointer->getRecursiveSummaryFields());
		}
		
		return $this->recursiveSummaryfields;
	}
	
	function setPrimaryKey($string){$this->primary_key = $string;}
	function setSummaryFields($fields){$this->$summary_fields = $fields;}
	function setWhere($where){$this->$where = $where;}  //may be used for showing nearby states
	function setParentTable($table_info){$this->parent_table = &$table_info;}
	
	function getTableName(){ return $this->table;}  // for example: office_contacts 
	function getForeignKeys(){return $this->foreign_keys;} //for example: 'office_id' => '22'.  
	function getSummaryFields(){return $this->summary_fields;} // " name, email, phone, status
	function getPrimaryKey(){return $this->primary_key;}
	function getParentTable(){return $this->parent_table;}
}

class df_M2M_table_info extends df_table_info {
	protected $primaryJoined = '', $primaryJoinedColName = '', $otherJoined;
	
	// php calls the nearest constructor, this is unneeded:
	// function __construct($table, $foreign_keys='',$summary_fields=''){
		// parent::__construct($table, $foreign_keys, $summary_fields);
	// }

	
	//should return an array key/val pair, but left for historical reasons:
	function getPrimaryJoined(){
		if ($primaryJoined != '') {return $primaryJoined;}
		else{
			foreach ($this->foreign_keys as $fKeyName => $fKeyVal){
				if (is_object($fKeyVal)){ //return the first linked table
					return $fKeyVal;
				}
			}
			
		}
	}
	function getPrimaryJoinedColName(){
		if ($primaryJoinedColName != '') {return $primaryJoinedColName;}
		else{
			foreach ($this->foreign_keys as $fKeyName => $fKeyVal){
				if (is_object($fKeyVal)){ //return the first linked table
					return $fKeyName;
				}
			}
			
		}
	}
	
	//todo imrpove code here
	function getOtherJoined(){
		if (isset($otherJoined)) return $otherJoined;
		
		$first = true;
		$otherJoined = Array();
		
		foreach ($this->foreign_keys as $fKeyName => $fKeyVal){
			if (is_object($fKeyVal)){ 
				if ($first == true){ $first = false;}
				else{
					$otherJoined[$fKeyName] = $fKeyVal;
				}
			}
		}
		
		return $otherJoined;
	}
}


function df_createTab($tabName, $tabContent){
	global $modx;
	$e = &$modx->Event;		
		
	$tab = '	
	<div class="tab-page" id="tab'.$tabName.'">
		<h2 class="tab">'.$tabName.'</h2>
		<div class="tabIntro" id="tab-intro-'.$tabName.'">'.$tabContent.'</div>
	</div>';
		
	$e->output($tab);	
}

//half finished and unused.  would need a good way to get data to the php script in the end.  JSON stuff?
function df_create_ajax_tab($tabName, $scriptName){
	if (df_useThisDocument($roles, $templates, $doc, $current_doc_id)) {
		global $modx;
		$e = &$modx->Event;
				
		$tabScript .= "<script type='text/javascript'>j(this.parent).click(function(e){ajaxTab('M2M',e.target.parent);});</script>";
		
		$tab = '	
		<div class="tab-page" id="tab'.$tabName.'">
			<h2 class="tab">'.$tabName.'</h2>
			<div class="tabIntro" id="tab-intro-'.$tabName.'">
				<h2>Loading...</h2>'
		.		"<script type='text/javascript'>j('#tab$tabName').click(function(e){e.preventDefault();ajaxTab('M2M',e.target.parent);});</script>"
		.'		</div>
		</div>';

		$e->output($tab);		
	}
}

//creates a tab for a one to many dtabase connected to a document
function df_createO2MTab($plural_name, $singular_name, &$table_info, $current_doc_id, $roles='', $templates='', $doc='', $plugin_cell=''){
	// if the current page is being edited by someone in the list of roles, and uses a template in the list of templates
	//todo: allow specific document..
	
	// echo "<script type='text/javascript'>alert('role wanted: $roles tpl wanted: $templates doc wanted: $doc, current doc: $current_doc_id (==$doc2)');</script>";
	
	if (df_useThisDocument($roles, $templates, $doc, $current_doc_id)) {

		//could use parseDocumentSource here instead to include snippets, chunks, etx 
		ob_start();
		include('frolic_O2M.php');  //change this line to include a custom file
		$tab_content = ob_get_contents();
		ob_end_clean();
		
		df_createTab($plural_name, $tab_content);
	}
}

//creates a tab for a many to many relationship.  Keep these functions distinct for beta in case different variables are needed for the M2M.php
// in table info, the first foreign key is just a value of the column which contains the current resource key, the first _associative_ array item indicates the data in question (the content of the tab.)  Additional associative columns are for helping fill out the table (such as converting an id to a description)
function df_createM2MTab($plural_name, $singular_name, &$table_info, $current_doc_id, $roles='', $templates='', $doc=''){
	if (df_useThisDocument($roles, $templates, $doc, $current_doc_id)) {
		ob_start();
		include('frolic_M2M.php');  //change this line to include a custom file
		$tab_content = ob_get_contents();
		ob_end_clean();
		
		df_createTab($plural_name, $tab_content);
	}
}

function df_parse_plugin_cell($plugin_cell, $article_id){
	if ($plugin_cell != '')	{
		eval($plugin_cell);
		//$plugin_cell = '$tdData = make_publish_links($article_id);';
		return '<td onclick="cancelProp(event);">'.$tdData.'</td>';
	}
}


function df_useThisDocument($roles='', $templates='', $doc_id='', $current_doc_id){
	// global $current_doc_id; //I have no idea why, but this gives nothing.  so use args.
	if ($doc_id != '' && $doc_id == $current_doc_id){
		return true;
		
	}else if ($doc_id==''){ //only if blank, otherwise rules and template left blank will return true.
		return useThisRule($roles, $templates);
	}
	return false;
}

function df_is_foreign_field($fieldName, $foreign_keys){
	 return (strlen($foreign_keys) > 0 && array_key_exists( $fieldName, $foreign_keys) && is_object($foreign_keys[$fieldName]));
}

function df_is_document_field($fieldName, $foreign_keys){
	 return (strlen($foreign_keys) > 0 && array_key_exists( $fieldName, $foreign_keys) && is_string($foreign_keys[$fieldName]));
}

?>



